home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / python-support / python-rdflib / rdflib / syntax / serializers / TurtleSerializer.py < prev    next >
Encoding:
Python Source  |  2007-04-04  |  5.8 KB  |  207 lines

  1. import urlparse
  2. from xml.sax.saxutils import escape, quoteattr
  3.  
  4. from rdflib.BNode import BNode
  5. from rdflib.Literal import Literal
  6. from rdflib.URIRef import URIRef
  7. from rdflib.syntax.xml_names import split_uri 
  8.  
  9. from rdflib.syntax.serializers.RecursiveSerializer import RecursiveSerializer
  10. from rdflib.exceptions import Error
  11.  
  12. from rdflib import RDF, RDFS
  13.  
  14. SUBJECT = 0
  15. VERB = 1
  16. OBJECT = 2
  17.  
  18.  
  19.  
  20. class TurtleSerializer(RecursiveSerializer):
  21.  
  22.     short_name="turtle"
  23.     indentString = "    "
  24.     def __init__(self, store):
  25.         super(TurtleSerializer, self).__init__(store)
  26.         self.reset()
  27.         self.stream = None
  28.  
  29.     def reset(self):
  30.         super(TurtleSerializer, self).reset()
  31.         self._shortNames = {}
  32.         self._started = False
  33.     
  34.     def getQName(self, uri):
  35.         if isinstance(uri, URIRef):
  36.             try:
  37.                 parts = self.store.compute_qname(uri)
  38.             except Exception, e:
  39.                 parts = None
  40.             if parts:
  41.                 
  42.                 prefix, namespace, local = parts
  43.                 if local.find(".")!=-1:
  44.                     # Local parts with . will mess up serialization
  45.                     return None
  46.                 
  47.                 self.addNamespace(prefix, namespace)
  48.                 return u"%s:%s" % (prefix, local)
  49.         return None
  50.  
  51.     def preprocessTriple(self, triple):
  52.         super(TurtleSerializer, self).preprocessTriple(triple)
  53.         for node in triple:
  54.             self.getQName(node)
  55.         p = triple[1]
  56.         if isinstance(p, BNode):
  57.             self._references[p] = self.refCount(p) +1
  58.             
  59.     def label(self, node):
  60.         qname = self.getQName(node)
  61.         if qname is None:
  62.             return node.n3()
  63.         return qname
  64.  
  65.     def startDocument(self):
  66.         self._started = True
  67.         ns_list= list(self.store.namespaces())
  68.         ns_list.sort()
  69.         if len(ns_list) == 0:
  70.             return
  71.         
  72.         for prefix, uri in ns_list:
  73.             self.write('\n'+self.indent()+'@prefix %s: %s.'%(prefix, uri))
  74.         self.write('\n')
  75.  
  76.     def endDocument(self):
  77.         pass
  78.  
  79.     def isValidList(self,l): 
  80.         """Checks if l is a valid RDF list, i.e. no nodes have other properties."""
  81.         try:
  82.             if not self.store.value(l, RDF.first):
  83.                 return False
  84.         except: 
  85.             return False
  86.         while l:
  87.             if l!=RDF.nil and len(list(self.store.predicate_objects(l)))!=2: return False
  88.             l = self.store.value(l, RDF.rest)
  89.         return True
  90.         
  91.     def doList(self,l):
  92.         while l:
  93.             item = self.store.value(l, RDF.first)
  94.             if item:
  95.                 self.path(item, SUBJECT)
  96.                 self.subjectDone(l)
  97.             l = self.store.value(l, RDF.rest)
  98.             
  99.     def p_squared(self, node, position):
  100.         if (not isinstance(node, BNode)
  101.             or node in self._serialized
  102.             or self.refCount(node) > 1
  103.             or position == SUBJECT):
  104.             return False
  105.        
  106.         if self.isValidList(node): 
  107.             # this is a list
  108.             self.write(' (')
  109.             self.depth+=2
  110.             self.doList(node)
  111.             self.depth-=2            
  112.             self.write(' )')
  113.             return True
  114.         
  115.         self.subjectDone(node)
  116.         self.write(' [')
  117.         self.depth += 2
  118.         self.predicateList(node)
  119.         self.depth -= 2
  120.         self.write(']')
  121.         return True
  122.  
  123.     def p_default(self, node, ignore):
  124.         self.write(" "+self.label(node))
  125.         return True
  126.     
  127.     def path(self, node, position):
  128.         if not (self.p_squared(node, position)
  129.                 or self.p_default(node, position)):
  130.             raise Error("Cannot serialize node '%s'"%(node, ))
  131.  
  132.     def verb(self, node):
  133.         if node == RDF.type:
  134.             self.write(' a')
  135.         else:
  136.             self.path(node, VERB)
  137.     
  138.     def objectList(self, objects):
  139.         if len(objects) == 0:
  140.             return
  141.  
  142.         self.path(objects[0], OBJECT)
  143.         for obj in objects[1:]:
  144.             self.write(',\n'+self.indent(2))
  145.             self.path(obj, OBJECT)
  146.  
  147.     def predicateList(self, subject):
  148.         properties = self.buildPredicateHash(subject)
  149.         propList = self.sortProperties(properties)
  150.         if len(propList) == 0:
  151.             return
  152.  
  153.         self.verb(propList[0])
  154.         self.objectList(properties[propList[0]])
  155.         for predicate in propList[1:]:
  156.             self.write(';\n'+self.indent(1))
  157.             self.verb(predicate)
  158.             self.objectList(properties[predicate])
  159.  
  160.     def s_squared(self, subject):
  161.         if (self.refCount(subject) > 0) or not isinstance(subject, BNode):
  162.             return False
  163.         self.write('\n'+self.indent()+" [")
  164.         self.depth+=1
  165.         self.predicateList(subject)
  166.         self.depth-=1
  167.         self.write('].')
  168.         return True
  169.  
  170.     def s_default(self, subject):
  171.         self.write('\n'+self.indent())
  172.         self.path(subject, SUBJECT)
  173.         self.predicateList(subject)
  174.         self.write('. ')
  175.         return True
  176.     
  177.     def statement(self, subject):
  178.         self.subjectDone(subject)
  179.         if not self.s_squared(subject):
  180.             self.s_default(subject)
  181.             
  182.  
  183.     def serialize(self, stream, base=None, encoding=None, **args):
  184.         self.reset()
  185.         self.stream = stream
  186.         self.base=base
  187.         
  188.         # In newer rdflibs these are always in the namespace manager
  189.         #self.store.prefix_mapping('rdf', RDFNS)
  190.         #self.store.prefix_mapping('rdfs', RDFSNS)
  191.         
  192.         self.preprocess()
  193.         subjects_list = self.orderSubjects()
  194.  
  195.         self.startDocument()
  196.  
  197.         firstTime = True
  198.         for subject in subjects_list:
  199.             if not self.isDone(subject):
  200.                 if firstTime:
  201.                     firstTime = False
  202.                 else:
  203.                     self.write('\n')
  204.                 self.statement(subject)
  205.         
  206.         self.endDocument()
  207.